package top.yekongle.feature.java8.stream;

import org.junit.Ignore;
import org.junit.Test;
import top.yekongle.feature.java8.lambda.Employee;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * 一、Stream 的三个操作步骤
 * 1. 创建 Stream
 * 2. 中间操作
 * 3. 终止操作(终端操作)
 *
 */
public class TestStream2 {

    /*
        筛选与切片
        filter > 接收 Lambda，从流中排除某些元素
        limit > 截断流，使其元素不超过给定数量
        skip(n) > 跳过元素，返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个，则返回一个空流。与 limit(n) 互补
        distinct > 筛选，通过流所生成元素的 hashCode() 和 equals() 去除重复元素

     */

    List<Employee> employees = Arrays.asList(
            new Employee("张三", 18, 5555.55, null),
            new Employee("李四", 19, 6666.66, null),
            new Employee("王五", 40, 7777.77, null),
            new Employee("王五", 40, 7777.77, null),
            new Employee("王五", 40, 7777.77, null)
    );

    // 内部迭代：迭代操作由 Stream API 完成
    
    public void test1() {
        // 中间操作： 不会执行任何操作
        Stream<Employee> s = employees.stream()
                .filter((e) -> e.getAge() > 35);

        // 终止操作：一次性执行全部内容，即 "惰性求值"
//        s.forEach(System.out::println);
    }

    
    public void test2() {
        employees.stream()
                .filter((e) -> e.getSalary() > 3000)
                .limit(2)
                .forEach(System.out::println);
    }

    
    public void test3() {
        employees.stream()
                .filter((e) -> e.getSalary() > 2000)
                .skip(2)
                .forEach(System.out::println);
    }

    
    public void test4() {
        employees.stream()
                .filter((e) -> e.getSalary() > 2000)
                .distinct()
                .forEach(System.out::println);
    }


//    映射 map > 接收 Lambda，将元素转换成其他形式或提取信息。接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成
//        一个新的元素。
//        flatMap > 接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流
    
    public void test5() {
        List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");

        list.stream()
                .map((str) -> str.toUpperCase())
                .forEach(System.out::println);

        employees.stream()
                .distinct()
                .map(Employee::getName)
                .forEach(System.out::println);
    }

    
    public void test6() {
        List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");

        Stream<Stream<Character>> stream = list.stream().map(TestStream2::filterCharacter);

        stream.forEach((s)-> {
            s.forEach(System.out::println);
        });

        Stream<Character> sm = list.stream()
                .flatMap(TestStream2::filterCharacter);
        sm.forEach(System.out::println);
    }

    public static Stream<Character> filterCharacter(String str) {
        List<Character> list = new ArrayList<>();
        for (Character ch : str.toCharArray()) {
            list.add(ch);
        }
        return list.stream();
    }

}